import type * as React from 'react';
import { isArray } from 'lodash-es';
import { defineFields } from '@/lib/defineFields';

import { type TWidget } from './types';

const SYMBOL_INTERNAL = Symbol('internalSymbol') as symbol;
const screenSet = new Set();

const InternalFields = {
    WIDGET_VISIBLE: 'widgetVisible',
    WIDGET_GROUP_VISIBLE_FILTER: 'widgetGroup:visibleFilter',
} as const;

const internalFieldsSet = new Set([
    //
    'enableControl',
    'global',
    'highlight',
    'downplay',
    InternalFields.WIDGET_VISIBLE,
    InternalFields.WIDGET_GROUP_VISIBLE_FILTER,
]);

const internalFields = defineFields([
    { name: 'global', value: 'global', [SYMBOL_INTERNAL]: true },
    { name: 'highlight', value: 'highlight', [SYMBOL_INTERNAL]: true },
    { name: 'downplay', value: 'downplay', [SYMBOL_INTERNAL]: true },
    { name: InternalFields.WIDGET_VISIBLE, value: InternalFields.WIDGET_VISIBLE, [SYMBOL_INTERNAL]: true },

    /**
     * 派发数据应该是数组
     */
    {
        name: InternalFields.WIDGET_GROUP_VISIBLE_FILTER,
        value: InternalFields.WIDGET_GROUP_VISIBLE_FILTER,
        [SYMBOL_INTERNAL]: true,
    },
]);

const internalDispatcher = {
    widgetGroupVisibleFilter: (ownerProps: any, data: any) => {
        const dispatchData = isArray(data) ? data : [data];
        ownerProps.dispatch(internalFields.getField('widgetGroup:visibleFilter'), dispatchData);
    },
};

const generateGroupId = (group: string | number) => `@@Group##[${group}]%%*@@`;

const createLargeScreen = (screenName: string) => {
    console.log(`%c[当前大屏为：${screenName}]`, 'background:#080;color:#fff;padding: 2px 5px;border-radius: 2px;line-height:13px;', {
        screen: screenName,
    });
    screenSet.add(screenName);

    const widgetsMapping = new Map<string, TWidget>();

    let count = 0;
    const registerWidget = (opts: {
        name: any;
        element: React.ComponentType | React.LazyExoticComponent<any>;
        layout: TWidget['layout'];
        style?: TWidget['style'];
        group?: string | number;
        animateCss?: TWidget['animateCss'];
        subscribe?: Record<string, any>;
    }) => {
        count++;

        widgetsMapping.set(opts.name, {
            screen: screenName,
            widgetName: opts.name,
            element: opts.element,
            id: `@@screen@@${screenName}##widget@@${opts.name}@@${count}@@`,
            groupFilterId: generateGroupId(opts.group ?? 'default'),
            layout: Object.assign({ width: 400, height: 300, left: 0, top: 0 }, opts.layout || {}),
            style: opts.style,
            animateCss: opts.animateCss as any,
            control: { subscribe: opts.subscribe },
        });
    };

    const getWidgets = () => {
        return [...widgetsMapping.values()];
    };

    const defineInteractionFields: typeof defineFields = (fields) => {
        if (fields.some((f: any) => internalFieldsSet.has(f.name) || internalFieldsSet.has(f.value))) {
            throw new Error(`请不要使用内置字段,${[...internalFieldsSet]}`);
        }

        return defineFields(fields);
    };

    return {
        registerWidget,
        getWidgets,
        defineInteractionFields,
        internalFields,
        internalDispatcher,
        get screenName() {
            return screenName;
        },
        deleteScreen: () => {
            screenSet.delete(screenName);
        },
    };
};

const isInternalField = (field: any) => {
    const realField = internalFields.getField(field.name);
    return realField && (realField[SYMBOL_INTERNAL] as boolean);
};

export {
    //
    createLargeScreen,
    isInternalField,
    InternalFields,
    generateGroupId,
    internalDispatcher,
    screenSet as LargeScreenSet,
};

export type { TWidget };
